home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / pctjsp86.arc / ADRPROG next >
Text File  |  1986-07-18  |  8KB  |  173 lines

  1. ( name task )                    ( use base 10 )
  2. TASK ADRPROG                     DECIMAL
  3.  
  4. ( length of record )             ( max num of records )
  5. 200 CONSTANT RECLEN              100 CONSTANT MAX-REC
  6.  
  7. ( str. variable for filename )   ( initialize filename )
  8. 12 $VARIABLE ADR-FILE            $" TESTFILE.ADR" ADR-FILE $!
  9.  
  10. ( variable for file handle )     ( initialize to 0 )
  11. VARIABLE ADRHNDL                 0 ADRHNDL !
  12.  
  13. ( string constant containing item delimiter )
  14. $" |" $CONSTANT DELIM
  15.  
  16. ( byte array to show if record used; 0 if record free, 1 if used )
  17. MAX-REC CARRAY REC-USE
  18.  
  19. ( initialize MAX-REC elements to zero )
  20. 0 REC-USE MAX-REC 0 FILL
  21.  
  22. 255 $VARIABLE TEST$ ( string variable for search string )
  23.  
  24. \ comment after a word name shows stack contents before and after.
  25. \ MAKE-ADR-FILE is normally used as ADR-FILE MAKE-ADR-FILE
  26. \ and must be used at leas once to set up a file to which records
  27. \ may be added with ENTER-ADR
  28. : MAKE-ADR-FILE ( $adr -- )
  29.   DUP ADR-FILE $! MAKE-OUTPUT ( store name, make file)
  30.   ( next line vectors output to file and initializes MAX-REC number )
  31.   ( of zeros in start of file; used to store REC-USE array )
  32.   ( CRT vectors output back to the video screen )
  33.   >FILE   MAX-REC 0   DO 0 EMIT LOOP   CRT   CLOSE-OUTPUT ;
  34. \ if ADRHNDL contains less than 5 file has not been opened
  35. : OKFILE? ( -- ) ADRHNDL @ 5 < ABORT" File not open." ;
  36. \ returns number of first free record in file, looking at REC-USE
  37. : FIND-FREE ( -- first-free-rec-num )
  38.   MAX-REC 0 DO
  39.     ( LEAVE exits loop if REC-USE entry of 0 is found, with )
  40.     ( loop index on the stack )
  41.     I REC-USE C@ 0=    IF I LEAVE THEN
  42.     ( if I+1 reaches MAX-REC there is no 0 entry in REC-USE )
  43.     MAX-REC I 1+ = ABORT" No room for record."
  44.   LOOP ;
  45. \ calculate offset of file pointer given record number
  46. : FIND-PTR ( rec-num -- lo of ptr ) RECLEN 2+ * MAX-REC + ;
  47. \ sets MS-DOS's file pointer to calculated file pointer for a record
  48. : FIND-REC ( rec-num -- )   OKFILE?
  49.   ( LSEEK expects lo val. of pointer, hi val. of pointer, handle )
  50.   ( on stack, then sets MS-DOS pointer with 42 hex system function )
  51.   ( call; DROPs needed because LSEEK returns pointer value )
  52.   FIND-PTR 0 ADRHNDL @ LSEEK DROP DROP ;
  53. \ puts the low value of the end of file pointer on the stack
  54. : FIND-EOF ( -- lo of EOF ) OKFILE?
  55.   ( LSEEK++ with 0 as lo offset, 0 as hi offset, and handle on stack )
  56.   ( sets MS-DOS pointer to EOF and returns lo and hi value of EOF )
  57.   0 0 ADRHNDL @ LSEEK++
  58.   ( set pointer to SOF, drop all but lo value of EOF )
  59.   0 0 ADRHNDL @ LSEEK DROP DROP DROP ;
  60. \ opens for output the filename stored in ADR-FILE ; sets ADRHNDL
  61. \ to value of handle returned by OPEN-OUTPUT
  62. : OPEN-ADR-OUT ( -- ) ADR-FILE OPEN-OUTPUT OUTPUT @ ADRHNDL ! ;
  63. \ if output file is open, closes it, resets ADRHNDL
  64. : CLOSE-ADR-OUT ( -- ) OKFILE? CLOSE-OUTPUT OUTPUT @ ADRHNDL ! ;
  65. \ same as OPEN-ADR-OUT , but for input file
  66. : OPEN-ADR-IN ( -- ) ADR-FILE OPEN-INPUT INPUT @ ADRHNDL ! ;
  67. \ same as CLOSE-ADR-OUT , but for input file
  68. : CLOSE-ADR-IN ( -- ) OKFILE? CLOSE-INPUT INPUT @ ADRHNDL ! ;
  69. \ if number of bytes put into record is greater than the
  70. \ number in RECLEN , it is an error; ABORT
  71. : TOOBIG? ( len of entry -- ) RECLEN > ABORT" Record full." ;
  72. \ fetch and store item; expects number of bytes already put into
  73. \ record on stack, asks for string input with IN$ , fetches length
  74. \ from count byte of string, adds 1 for delimiter that will be put
  75. \ in, ROT rotates third on stack, old record count, to top, +
  76. \ calculates new record byte count, DUP duplicates it, TOOBIG?
  77. \ checks for record overrun error
  78. : @&!ITEM ( used -- new-used ) IN$ DUP C@ 1+ ROT + DUP TOOBIG?
  79.   ( SWAP puts string addr on top of stack, >FILE $. DELIM $. CRT )
  80.   ( vectors output to file, prints inputted string, prints end of )
  81.   ( item marker, |, and returns output to video display )
  82.   SWAP >FILE $. DELIM $. CRT ;
  83. \ moves the contents of REC-USE from the file to the array
  84. : GET-REC-USE ( -- ) OPEN-ADR-IN
  85.   ( <FILE vectors input from file, MAX-REC GX takes first MAX-REC )
  86.   ( bytes from the file to a string; 1+ 0 REC-USE MAX-REC CMOVE )
  87.   ( moves the bytes into the REC-USE array; then closes file )
  88.   <FILE MAX-REC GX KBRD 1+ 0 REC-USE MAX-REC CMOVE CLOSE-ADR-IN ;
  89. \ moves the contents of REC-USE from the array to the file
  90. : PUT-REC-USE ( -- ) OPEN-ADR-OUT
  91.   ( LSEEK sets MS-DOS pointer to start of file, then )
  92.   ( 0 REC-USE MAX-REC >FILE TYPE "types" contents to file )
  93.   0 0 ADRHNDL @ LSEEK DROP DROP 0 REC-USE MAX-REC >FILE TYPE CRT
  94.   CLOSE-ADR-OUT ;
  95. \ queries user for information then puts to file
  96. : ENTER-ADR ( -- )
  97.   ( gets REC-USE contents from file and finds a free record number )
  98.   GET-REC-USE FIND-FREE
  99.   ( marks the record used by storing a 1 in the byte, puts to file )
  100.   1 OVER REC-USE C! PUT-REC-USE
  101.   ( open file and move MS-DOS pointer to start of record )
  102.   OPEN-ADR-OUT  FIND-REC 0
  103.   ( query for information and store to file )
  104.   CR ." Name"       @&!ITEM
  105.   CR ." Street"     @&!ITEM
  106.   CR ." City/State" @&!ITEM
  107.   CR ." Phone"      @&!ITEM
  108.   CR ." Comment"    @&!ITEM
  109.   ( fill to end of record with 255 ASCII [ignored] and close file )
  110.   ( "printing" a CR or carriage return to file makes EOR marker )
  111.   >FILE RECLEN SWAP - 0 DO 255 EMIT LOOP CR CRT CLOSE-ADR-OUT ;
  112. \ LIMIT$ is an array containing the input delimiters used by parser
  113. \ this sets 124, ASCII for |, the item delimiter, as needed in LIMIT$
  114. : SET-DELIM 124 LIMIT$ 1 + C! 124 LIMIT$ 2 + C! 124 LIMIT$ 3 + C! ;
  115. \ FIND-NAME accepts a string address on the stack and searches the
  116. \ name fields of each record to see if the string is any part of a
  117. \ name string. It then displays the record number and name string
  118. \ that was found..
  119. : FIND-NAME ( $addr -- )
  120.   ( store the search string in TEST$ ; sets | delimiter for parsing )
  121.   TEST$ $! SET-DELIM
  122.   ( open file, vector from file, GC , get cursor, does tab )
  123.   ( to beyond where the byte array is stored )
  124.   OPEN-ADR-IN <FILE MAX-REC GC
  125.   ( start search in loop; R# @ returns record number counter. If it )
  126.   ( is zero the EOF was found so file is closed, control is returned )
  127.   ( to the keyboard by KBRD , and message is given )
  128.   MAX-REC 0  DO   R# @ 0=
  129.     IF CLOSE-ADR-IN KBRD CR ." Search complete." ABORT THEN
  130.     ( G$ parses item using delimiter in LIMIT$ ; DUP TEST$ INSTR )
  131.     ( returns non-zero or true if search string was in parsed string )
  132.     G$ DUP TEST$ INSTR
  133.     ( if string found show with $. and display record was found in )
  134.     IF CR $. ."  Found in record " I .
  135.     ELSE DROP ( otherwise drop the address of the parsed string )
  136.     THEN
  137.     NR        ( go to the next record and do again with loop )
  138.   LOOP KBRD CLOSE-ADR-IN CR ." Search complete." ;
  139. \ SHOW-ADR expects record number on stack and displays contents
  140. : SHOW-ADR ( rec# -- )
  141.   ( return a true if the record is empty and abort with message )
  142.   DUP GET-REC-USE REC-USE C@ 0= ABORT" Empty record"
  143.   ( set up the delimiters and open the file )
  144.   SET-DELIM OPEN-ADR-IN
  145.   ( return a true if the needed pointer is beyond the EOF )
  146.   DUP FIND-PTR FIND-EOF >=
  147.   ( and if it is close the file with an error message )
  148.   IF DROP CLOSE-ADR-IN CR ." Beyond EOF." ABORT THEN
  149.   ( set the MS-DOS pointer to the start of record and vector input )
  150.   FIND-REC <FILE
  151.   ( parse 5 items and display them, then close file )
  152.   5 0 DO CR G$ $. LOOP KBRD CLOSE-ADR-IN ;
  153. \ DEL-ADR displays the contents of a record and asks if it should be
  154. \ deleted. If yes, the appropriate element in REC-USE is set to 0
  155. \ and the record is blanked by placing 5 | delimiters with nothing
  156. \ between them in the record
  157. : DEL-ADR ( rec# -- ) DUP SHOW-ADR
  158.   ( KEY gets a character from the keyboard; if it is not ASCII 89 )
  159.   ( which is Y, the function is aborted )
  160.   CR ." Delete it (Y/N)? " KEY DUP EMIT 89 <> IF ABORT THEN
  161.   ( get the array, store 0 as needed put it to file, find the record )
  162.   GET-REC-USE 0 OVER REC-USE C! PUT-REC-USE OPEN-ADR-OUT FIND-REC
  163.   ( vector output to file and write 5 consecutive delimiters )
  164.   >FILE 5 0 DO DELIM $. LOOP CRT
  165.   CLOSE-ADR-OUT ;
  166. -REC
  167.   ( vector output to file and write 5 consecutive delimiters )
  168.   >FILE 5 0 DO DELIM $. LOOP CRT
  169.   CLOSE-ADR-OUT ;
  170.  
  171.  
  172.  
  173.